package com.tenbit.tbw.svc;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import oracle.net.aso.p;

import org.apache.ibatis.transaction.Transaction;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;

import com.tenbit.tbw.dao.CodeBookManagementEDAO;
import com.tenbit.tbw.vo.SYS1010VO;
import com.tobesoft.platform.Platform;
/**
 * 코드북 관리 담당SVC <br>
 * <PRE>
 * System Name : 텐비트 워크샵
 * Business Name : 시스템(SYS)
 * Author : 김창섭
 * Class Name(en) : SYS1010SVCImpl.java
 * Class Name(ko) : 코드북관리 SVC 인터페이스 구현
 * Description  : 코드북 데이터 유효성 테스트, 목록조회,입력,수정,저장 담담 SVC 기능구현
 * Modification History
 *     수정일         수정자     수정내용
 *    ------------  -------  ---------------------------
 *    2014.04.29.   김창섭   	 최초 생성
 * </PRE>
 */
@Service
public class SYS1010SVCImpl implements SYS1010SVC{
	
	private Logger log=Logger.getLogger(this.getClass());
	
	@Autowired
	private CodeBookManagementEDAO dao;
	
	private Map<String,Object> resultMap=new HashMap<String,Object>();
	boolean result=false;
	private String msg=null;
	
	/**
	  * 분류코드목록 조회
	  * @param   paramMap type:, name: 
	  * @return  Map resultMap:List<SYS1010VO> rows:상세코드 목록, boolean result:결과, String msg:결과 msg
	  */
	@Override
	public Map<String, Object> getCodeTypeList(Map<String, Object> paramMap) {
		// 분류 코드 목록 조회
		log.debug("===================분류코드목록 조회 시작 =================");
		
		List<SYS1010VO> rows=null;
		String type = (String) paramMap.get("type");
		String name = (String) paramMap.get("name");
		
		log.debug(paramMap);
		
		if((type==null||type.equals("")) &&(name==null||name.equals(""))){
			//type, name 값이 없을때
			paramMap.put("codeType", "");
			paramMap.put("codeName", "");
		} else if((type==null||type.equals(""))&&(name!=null&&!name.equals(""))){
			//type 값없고, name 값이 있을때
			paramMap.put("codeType", name);
			paramMap.put("codeName", name);
		} else if((type!=null&&!type.equals(""))&&(name==null||name.equals(""))){
			//type 값있고, name 값이 없을때
			if(type.equals("code")){
				paramMap.put("codeType", "");
				paramMap.put("codeName", "");
			}else if(type.equals("name")){
				paramMap.put("codeType", "");
				paramMap.put("codeName", "");
			}
		}else if((type!=null&&!type.equals(""))&&(name!=null&&!name.equals(""))){
			//type 값있고, name 값이 있을때
			if(type.equals("code")){
				paramMap.put("codeType", name);
				paramMap.put("codeName", "");
			}else if(type.equals("name")){
				paramMap.put("codeType", "");
				paramMap.put("codeName", name);
			}
		}
		
		resultMap.put("searchType", type);
		resultMap.put("searchName", name);
		
		
		try {
			rows=dao.listCodeType(paramMap);
		} catch (Exception e) {
			// 목록조회 예외 발생시
			e.printStackTrace();
			
			msg = "조회실패 :파라미터 명을 확인해 주세요";
			result=false;
			resultMap.put("msg", "msg");
			resultMap.put("result", "result");
			return resultMap;
		}
		log.debug(paramMap);
		result=true;
		resultMap.put("rows", rows);
		resultMap.put("result", "result");
		
		log.debug(resultMap);
		log.debug("===================분류코드목록 조회 종료 =================");
		return resultMap;
	}
	/**
	  * 코드명으로 상세 코드목록 조회
	  * @param   paramMap codeName:코드명
	  * @return  Map resultMap: List<SYS1010VO> rows:상세코드 목록, boolean result:결과, String msg:결과 msg
	  */
	@Override
	public Map<String, Object> getCodeDetailList(Map<String, Object> paramMap){
		// 상세코드 목록 조회
		
		log.debug("===================코드명으로 상세 코드 목록조회 시작=================");
		
		List<SYS1010VO> rows=null;
		log.debug(paramMap);
		try {
			rows=dao.listCodeDetail(paramMap);
		} catch (Exception e) {
			// 목록조회 예외 발생시
			e.printStackTrace();
			msg = "조회실패 :파라미터 명을 확인해 주세요";
			result=false;
			resultMap.put("msg", "msg");
			resultMap.put("result", "result");
			return resultMap;
		}
		result=true;
		msg="조회성공 :정상적으로 처리되었습니다.";
		resultMap.put("result", "result");
		resultMap.put("msg", msg);
		resultMap.put("rows", rows);
		
		log.debug(resultMap);
		log.debug("===================코드명으로 상세 코드 목록조회 종료=================");
		return resultMap;
	}
	
	/**
	  * 코드명으로 상세 코드 목록 조회
	  * @param   paramMap codeType:분류코드, codeName:코드명
	  * @return  Map resultMap: List<SYS1010VO> rows:상세코드 목록, boolean result:결과, String msg:결과 msg
	  */
	@Override
	public Map<String, Object> getCodeNameList(Map<String, Object> paramMap){
		
		log.debug("===================코드명으로 상세 모드 목록조회 시작 =================");
		
		List<SYS1010VO> rows=null;
		log.debug(paramMap);
		try {
			rows=dao.listCodeName(paramMap);
		} catch (Exception e) {
			// 목록조회 예외 발생시
			e.printStackTrace();
			msg = "조회실패 :파라미터 명을 확인해 주세요";
			result=false;
			resultMap.put("msg", "msg");
			resultMap.put("result", "result");
			return resultMap;
		}
	
		msg="조회성공 :정상적으로 처리되었습니다.";
		resultMap.put("msg", msg);
		resultMap.put("rows", rows);

		log.debug(resultMap);
		log.debug("===================코드명으로 상세 모드 목록조회 시작  =================");
		return resultMap;
	}
	
	/**
	  * 분류 코드목록 Insert,Update,Delete
	  * @param   List<SYS1010VO> vo: 분류코드 목록
	  * @return  Map resultMap:boolean result:결과, String msg:결과 msg
	  */
	@Override
	public Map<String, Object> setCodeBookInfo(List<Map<String,Object>> vo) {
		// 입력,수정,삭제,처리


		log.debug("===================분류코드 목록 Insert,Update,Delete 시작 =================");
		
		Map<String,Object> paramMap=new HashMap<String,Object>();
		
		int ins=0;
		int upd=0;
		int del=0;
		
		Map<String, Object> checkResult = new HashMap<String, Object> ();
		
		if(vo==null){//파라미터 null여부 확인
			result=false;
			msg = "처리실패 : 저장할 정보가 없습니다.";
			resultMap.put("result", result);
			resultMap.put("msg",msg);
			return resultMap;
		}else{
			
			
				checkResult=checkSetData(vo); //데이터 유효성 테스트
			
			
			if(!(Boolean) checkResult.get("result")){ //유효성 테스트 성공여부
				result=false;
				msg = (String) checkResult.get("msg");
				resultMap.put("result", result);
				resultMap.put("msg",msg);
				return resultMap;
			} else {
				for(int i=0;i<vo.size();i++){
					
					if(vo.get(i).get("sign").equals("I")){ //Insert 
						paramMap.put("codeType",(String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder", Integer.parseInt((String)vo.get(i).get("sortOrder")));
						try {
							dao.insCodeBook(paramMap);
							ins=ins+1;
						} catch (Exception e) {
							//insert 예외 발생
							
							
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Insert -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Insert -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
					}else if(vo.get(i).get("sign").equals("U")){//Update 
						paramMap.put("codeType", (String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder", Integer.parseInt((String)vo.get(i).get("sortOrder")));
						try {
							dao.setCodeBook(paramMap);
							upd=upd+1;
						} catch (Exception e) {
							// update 예외 발생
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Update -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Update -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
					}else if(vo.get(i).get("sign").equals("D")){//Delete
						paramMap.put("codeType", (String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder",Integer.parseInt((String)vo.get(i).get("sortOrder")));
						try {
								del=del+dao.delCodeBook(paramMap);
							
						} catch (Exception e) {
							// delete 예외발생
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Delete -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Delete -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
					}
				}
			}
		
		}
		
		result=true;
		msg="처리성공 : Insert: "+ins+"개, Update: "+upd+"개, Delete: "+del+"개 성공하였습니다.";
		
		resultMap.put("result",result);
		resultMap.put("msg",msg);
		
		log.debug(resultMap);
		log.debug("===================분류코드 목록 Insert,Update,Delete 종료 =================");
		return resultMap;
	}
	/**
	  * 상세 코드목록 Insert,Update,Delete
	  * @param   List<SYS1010VO> vo: 상세코드 목록
	  * @return  Map resultMap:boolean result:결과, String msg:결과 msg
	  */
	@Override
	public Map<String, Object> setCodeBookDetailInfo(List<Map<String,Object> > vo) {
		// 입력,수정,삭제,처리
		
		log.debug("===================상세코드 목록 Insert,Update,Delete 시작 =================");
		
		Map<String,Object> paramMap=new HashMap<String,Object>();
		
		int ins=0;
		int upd=0;
		int del=0;
		int rvo=0;
		
		Map<String, Object> checkResult = new HashMap<String, Object> ();
		
		if(vo==null){//파라미터 null여부확인
			result=false;
			msg = "처리실패 : 저장할 정보가 없습니다.";
			resultMap.put("result", result);
			resultMap.put("msg",msg);
			return resultMap;
		}else{
				checkResult=checkSetData(vo);//데이터 유효성 검사
			
			if(!(Boolean) checkResult.get("result")){
				result=false;
				msg = (String) checkResult.get("msg");
				resultMap.put("result", result);
				resultMap.put("msg",msg);
				return resultMap;
			} else {
				for(int i=0;i<vo.size();i++){
					
					if(vo.get(i).get("sign").equals("I")){//Insert
						paramMap.put("codeType",(String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder", Integer.parseInt((String)vo.get(i).get("sortOrder")));
						
						
						try {// Insert 시 분류코드 유무 확인
							rvo=dao.checkSetDetail(paramMap);
						} catch (Exception e) {
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Insert -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Update -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
						
						if(rvo<=0){//
							msg = "처리실패 : DB에 분류코드가 등록되어 있지 않습니다.";
							result=false;
							resultMap.put("result",result);
							resultMap.put("msg",msg);
							return resultMap;
							
						}else{
						
							try {
								dao.insCodeBook(paramMap);
								ins=ins+1;
							} catch (Exception e) {
								if(e instanceof DataIntegrityViolationException){
									msg = "처리실패 : Insert -"+vo.get(i);
									result=false;
									resultMap.put("result",result);
									resultMap.put("msg",msg);
									
								} else{
									
									e.printStackTrace();
									msg = "처리실패 : Update -"+vo.get(i);
									result=false;
									resultMap.put("result",result);
									resultMap.put("msg",msg);
								}
								TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
								return resultMap;
							}
						}
					}else if(vo.get(i).get("sign").equals("U")){//Update
						paramMap.put("codeType", (String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder", Integer.parseInt((String)vo.get(i).get("sortOrder")));
						try {
							dao.setCodeBook(paramMap);
							upd=upd+1;
						} catch (Exception e) {
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Insert -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Update -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
					}else if(vo.get(i).get("sign").equals("D")){//Delete
						paramMap.put("codeType", (String)vo.get(i).get("codeType"));
						paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
						paramMap.put("codeName", (String)vo.get(i).get("codeName"));
						paramMap.put("sortOrder",Integer.parseInt((String)vo.get(i).get("sortOrder")));
						try {
							dao.delCodeBook2(paramMap);
							del=del+1;
						} catch (Exception e) {
							// delete 예외발생
							if(e instanceof DataIntegrityViolationException){
								msg = "처리실패 : Insert -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
								
							} else{
								
								e.printStackTrace();
								msg = "처리실패 : Update -"+vo.get(i);
								result=false;
								resultMap.put("result",result);
								resultMap.put("msg",msg);
							}
							TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
							return resultMap;
						}
					}
				}
			}
		
		}
		
		result=true;
		msg="처리성공 : Insert: "+ins+"개, Update: "+upd+"개, Delete: "+del+"개 성공하였습니다.";
		
		resultMap.put("result",result);
		resultMap.put("msg",msg);
		
		log.debug(resultMap);
		log.debug("===================상세코드 목록 Insert,Update,Delete 종료 =================");
		return resultMap;
	}
	
	/**
	  * 데이터 유효성 검사
	  * @param   List<SYS1010VO> vo: 상세코드 목록
	  * @return  Map check:boolean result:결과, String msg:결과 msg
	  */	
	private Map<String, Object> checkSetData(List<Map<String, Object>> vo) {
		// 목록 입력 수정 삭제 DATA check
		log.debug("===================데이터 유효성 검사 시작 =================");
		
		int rvo=0;
		int rvo1=0;
		Map<String,Object> check=new HashMap<String,Object>();
		Map<String,Object> paramMap=new HashMap<String,Object>();
		
		if(vo!=null){
			for(int i=0;i<vo.size();i++)
			{
				if(vo.get(i).get("codeType").equals("")||vo.get(i).get("codeType")==null)
				{
					msg="처리실패 : 분류코드가 없습니다.";
					result=false;
					check.put("result", result);
					check.put("msg", msg);
					return check;
				} else if(vo.get(i).get("codeDetail").equals("")||vo.get(i).get("codeDetail")==null)
				{
					msg="처리실패 : 상세코드가 없습니다.";
					result=false;
					check.put("result", result);
					check.put("msg", msg);
					return check;
				} else if(vo.get(i).get("codeName").equals("")||vo.get(i).get("codeName")==null)
				{
					msg="처리실패 : 코드 명이 없습니다.";
					result=false;
					check.put("result", result);
					check.put("msg", msg);
					return check;
				} else if(vo.get(i).get("sortOrder").equals("")||vo.get(i).get("sortOrder")==null)
				{
					msg="처리실패 : 정렬 순서가 없습니다.";
					result=false;
					check.put("result", result);
					check.put("msg", msg);
					return check;
				}
						
				
				for(int j=0;j<vo.size();j++)
				{
					if(i!=j)
					{
						if((vo.get(i).get("sign").equals("I")||vo.get(i).get("sign").equals("U"))
								&&(vo.get(j).get("sign").equals("I")||vo.get(j).get("sign").equals("U")))
						{//insert,update 구분자 확인
							if(vo.get(i).get("codeType").equals(vo.get(j).get("codeType"))
									&& vo.get(i).get("codeDetail").equals(vo.get(j).get("codeDetail")))
							{//목록내 pk 중복값 여부 확인
								result=false;
								msg="처리실패 : Insert OR Update 처리 목록에 중복되는 PK가 있습니다.";
								check.put("result", result);
								check.put("msg", msg);
								return check;
							} else if(vo.get(i).get("codeName").equals(vo.get(j).get("codeName")))
							{//목록내 코드명 중복 여부 확인
								result=false;
								msg="처리실패 : Insert OR Update 처리 목록에 중복되는 코드명이 있습니다.";
								check.put("result", result);
								check.put("msg", msg);
								return check;
							}//if
							
						}//if
					}//if
				}//for j
				
				if(vo.get(i).get("sign").equals("I"))//insert 구분자일때
				{
				
					paramMap.put("codeType", (String)vo.get(i).get("codeType"));
					paramMap.put("codeDetail", (String)vo.get(i).get("codeDetail"));
					paramMap.put("codeName", (String)vo.get(i).get("codeName"));
					
					try {
						rvo=dao.checkSetCodeDetail(paramMap);//DB내 pk중복값 확인
						rvo1=dao.codeName(paramMap);//DB내 코드명 중복 값 확인
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}//try

					if(rvo>0){
						result=false;
						msg="처리실패 : DB에 중복되는 PK가 있습니다.";
						check.put("result", result);
						check.put("msg", msg);
						return check;
					}else if(rvo1>0){
						result=false;
						msg="처리실패 : DB에 중복되는 코드명이 있습니다.";
						check.put("result", result);
						check.put("msg", msg);
						return check;
					}//if
					
				}//if
			}//for i
		}//if
		result=true;
		msg="처리성공 : 정상적으로 처리 되었습니다.";
		check.put("result", result);
		check.put("msg", msg);
		
		log.debug(check);
		log.debug("===================데이터 유효성 검사 시작 =================");
		return check;
	}

	

}
